﻿/************************************************************************
 * SMLib - State Model Library
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     SMLib\Base\UndirectedGraph.cs
 * Description  :     Undirected Graph
 * Change log   :     -2013: Intial version
 * To Do        :     it is not complete nor tested deeply
 ************************************************************************/
using System;
using System.Collections.Generic;

namespace SMLib.Base
{

    /// <summary>
    /// This is the UN-directed graph
    /// </summary>
    /// <typeparam name="STATELABEL"></typeparam>
    /// <typeparam name="EDGELABEL"></typeparam>
    public class UndirectedGraph<STATELABEL, EDGELABEL>
    {
        public UndirectedGraph()
        {
            states = new List<STATELABEL>();
            edges = new List<Edge>();
        }

        public IEnumerator<Edge> AllEdges()
        {
            return edges.GetEnumerator();
        }

        public class Edge
        {
            public Edge(int src, int dst, EDGELABEL label)
            {
                this.srcIndex = src;
                this.dstIndex = dst;
                this.label = label;
            }

            int srcIndex, dstIndex;
            EDGELABEL label;

            public EDGELABEL Label
            {
                get
                {
                    return label;
                }
            }
			
			public int SrcIndex
			{
                get
                {
                    return srcIndex;
                }
            }	
			
			public int DstIndex
			{
                get
                {
                    return dstIndex;
                }
            }	
					
        }

        List<STATELABEL> states;
        List<Edge> edges;

        public void AddState(STATELABEL slb)
        {
            states.Add(slb);
        }

        public void AddEdge(STATELABEL src, STATELABEL dst, EDGELABEL edge)
        {
            int srcInd = FindState(src);
            if (srcInd == -1)
                AddState(src);
            int dstInd = FindState(src);
            if (dstInd == -1)
                AddState(dst);
            edges.Add(new Edge(srcInd, dstInd, edge));
        }

        int FindState(STATELABEL label)
        {
            for (int i = 0; i < states.Count; i++)
            {
                if (states[i].Equals(label))
                    return i;
            }
            return -1;
        }
    }
}
